home *** CD-ROM | disk | FTP | other *** search
/ TPUG - Toronto PET Users Group / TPUG Users Group CD / TPUG Users Group CD.iso / PET / S-Super PET / (s)tj.d64 / KEY1.2.ASM < prev    next >
Assembly Source File  |  2009-01-18  |  25KB  |  558 lines

  1. opt     nolist
  2.  
  3. MemEnd_         equ     $22     ;As defined by Waterloo
  4. Service_        equ     $32     ;As defined by Waterloo
  5. irq_            equ   $0108     ;As defined by Waterloo
  6. ACIAstatus      equ   $eff1     ;As defined in the SuperPET's hardware
  7.  
  8. ;  __  __  __  __  __  __  __  __  __  __  __  __  __  __  __  __  __  __  __
  9. ; /  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \
  10. ;|            K E Y B O A R D   I N I T I A L I Z A T I O N S                |
  11. ; \__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/
  12.  
  13.  
  14. stiffness       equ     $01     ;pause period between two consequtive pia reads
  15. repeat_delay    equ     $1e     ; 30 jiffies = 1/2 second ($1e in Waterloo code)
  16. repeat_cont     equ     $03     ;  3 jiffies = 1/20 second
  17.  
  18.  
  19. keyboard_init   equ     *       ;called to connect keyboard
  20.  
  21.         clr     Service_        ;set exit mode to TRUE when done
  22.  
  23.         ldd     #top_mem        ;set Waterloo's top of memory
  24.         std     MemEnd_
  25.  
  26.         ldb     #stiffness      ;set keyboard stiffness
  27.         stb     debounce
  28.  
  29.         ldb     #repeat_delay   ;select cold repeat frequency
  30.         stb     long_pause
  31.  
  32.         ldb     #repeat_cont
  33.         stb     short_pause     ;select warm repeat frequency
  34.  
  35.         ldd     #$ffff          ;used by verification routine
  36.         std     old_up_coord
  37.         std     old_down_coord
  38.         std     prev_coord
  39.  
  40.         stb     keyb_enable     ;enable the keyboard
  41.  
  42.         ldd     #irq_service_routine
  43.         std     irq_            ;link keyboard to IRQ  service routine
  44.  
  45. top_mem rts
  46.  
  47. ;  __  __  __  __  __  __  __  __  __  __  __  __  __  __  __  __  __  __  __
  48. ; /  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \
  49. ;|    D A T A   S E C T I O N   (W I L L   B E   M O V E D   I N    O S / 9)  |
  50. ; \__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/
  51.  
  52. hours           equ     $0160   ;will be moved elsewhere in OS/9
  53. hours_max       equ     24      ;24 hrs. clock
  54.  
  55. clock_status    equ     $e813   ;bit 7 is set on clock interrupt (1/60 sec.).
  56. pia_row         equ     $e810   ;writing a number between 0-9 will select a row
  57. pia_col         equ     $e812   ;reading the port clears the clock interrupt
  58.                                 ;and will return the column of the selected row
  59.  
  60. keyb_enable     equ     $0129   ;will be moved elsewhere in OS/9
  61.  
  62.  
  63. long_pause      rmb     $01     ;maximum delay (in jiffies) before repeat starts
  64. short_pause     rmb     $01     ;maximum delay (in jiffies) while repeating
  65. debounce        rmb     $01     ;will control stiffness of keyboard
  66. delay           rmb     $01     ;counter used for repeat key function
  67. prev_coord      rmb     $02     ;last column/row of previous key
  68. prev_key        rmb     $01     ;last ASCII value of previous key
  69.  
  70. old_up_coord    rmb     $02     ;used for 2 keys roll over recognition
  71. old_down_coord  rmb     $02     ;up = scanned up,  down = scanned down
  72. ;  __  __  __  __  __  __  __  __  __  __  __  __  __  __  __  __  __  __  __
  73. ; /  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \
  74. ;|                 I N T E R R U P T   H A N D L E R                          |
  75. ; \__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/
  76.  
  77. irq_service_routine     equ     *
  78.  
  79.         ldb clock_status        ;clock interrupts every 1/60 sec (bit 7)
  80.         if  lt
  81.             bsr clock           ;update real time clock
  82.             bsr keyboard        ;scan keyboard and update buffer
  83.             ldb pia_col
  84.         else
  85.             ldb ACIAstatus      ;clear ACIA interrupts (or add an ACIA driver)
  86.         endif
  87.  
  88.         rts
  89.  
  90. ;  __  __  __  __  __  __  __  __  __  __  __  __  __  __  __  __  __  __  __
  91. ; /  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \
  92. ;|                    C L O C K   D R I V E R                                 |
  93. ; \__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/
  94.  
  95. clock   equ     *               ;update the real time clock
  96.  
  97.         ldx #hours+4            ;X = pointer+4 to (hrs,min,sec,jiffies)
  98.         ldd #60*256+4           ;A = base 60 ,B = 4 digit to update
  99.  
  100.         loop
  101.             inc  ,-x            ;point to next digit and increment it
  102.             cmpa ,x             ;compare 60 againt it   ; similar code to that
  103.         quif hi                                         ; provided by A. Moise
  104.             clr  ,x             ;do modulo 60 add       ; in console.asm
  105.             decb                                        ; on (S)TB
  106.         until eq                ;update no more than 4 digits, for safety.
  107.  
  108.         decb                    ;if all 4 digits were updated
  109.         if  le                  ;then correct the hours
  110.             lda #hours_max      ;24 hours per day
  111.             cmpa ,x             ;x points to hours
  112.             if  ls
  113.                 clr ,x          ;do modulo 24 add
  114. ;  ___________________________________________________________________
  115. ; /                                                                   \
  116. ;|                              ;update the day of the month          |
  117. ;|              lbsr calendar   ;update the day of the week           |
  118. ;|                              ;update the month and year            |
  119. ; \___________________________________________________________________/
  120.              endif
  121.         endif
  122.  
  123.         rts
  124.  
  125. ;  __  __  __  __  __  __  __  __  __  __  __  __  __  __  __  __  __  __  __
  126. ; /  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \
  127. ;|   A D D   A   C H A R A C T E R   T O    K E Y B O A R D   B U F F E R    |
  128. ; \__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/
  129. ;                       to be replace in OS/9
  130.  
  131. ;                       add_char_to_buffer
  132. ;       Accumulator B contains the character to be added to
  133. ;               the keyboard buffer
  134. ;       All registers are restored to their original value.
  135.  
  136. kyptr1_         equ $012c       ; address of buffer pointer 1 (to be moved)
  137. kyptr2_         equ $012e       ; address of buffer pointer 2 (to be moved)
  138. kybuf_          equ $0130       ; address of start of buffer  (to be moved)
  139. kybuflen_       equ $28         ; length of buffer
  140.  
  141. add_char_to_buffer equ *        ;to be updated for OS/9 use
  142.  
  143.         pshs    d,x,cc
  144.  
  145.         sei
  146.         ldx     kyptr2_
  147.         leax    1,x                     ; increment the pointer
  148.         cmpx    #kybuf_+kybuflen_       ; past end of buffer?
  149.         if      eq
  150.                 ldx #kybuf_             ; wrap around to start of buffer
  151.         endif
  152.  
  153.         cmpx kyptr1_                    ; is the buffer filled?
  154.         if   ne
  155.              stb [kyptr2_]              ; save the character in the buffer
  156.              stx kyptr2_                ; update pointer 2
  157.         endif
  158.  
  159.         puls    d,x,cc,pc               ;restore registers, enable interrups
  160.                                         ;return from subroutine
  161.  
  162. ;  __  __  __  __  __  __  __  __  __  __  __  __  __  __  __  __  __  __  __
  163. ; /  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \
  164. ;|                   K E Y B O A R D   H A N D L E R                         |
  165. ; \__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/
  166.  
  167. keyboard        equ     *       ;scan the keyboard and update the keyboard
  168.                                 ;buffer if necessary
  169.  
  170.         ldb keyb_enable         ;is the keyboard enabled?
  171.         if  ne                  ;$00 = disabled, $ff = enabled
  172.             bsr scan_keyboard   ;return key's coordinates
  173.             if  eq              ;cc  = zero if no key is depressed
  174.                 std prev_coord  ;ensure that the next key will be treated
  175.                 lda long_pause  ; as a new one
  176.                 sta delay
  177.             else                ;cc <> zero therefore a key is depressed
  178.                 cmpd prev_coord
  179.                 if  eq          ;was this key depressed during last interrupt ?
  180.                     dec delay
  181.                     if  eq      ;if delay time had elapsed
  182.                         lda short_pause
  183.                         sta delay
  184.                         ldb prev_key
  185.                         bsr add_char_to_buffer
  186.                     endif
  187.                 else            ;this key is different from the last one
  188.                     std prev_coord
  189.                     lbsr convert_to_ascii
  190.                     stb prev_key
  191.                     bsr add_char_to_buffer
  192.                     lda long_pause
  193.                     sta delay
  194.                 endif
  195.             endif
  196.         else
  197.             ldb #9                      ;re-enable the keyboard by
  198.             stb pia_row                 ;pressing "_" and STOP simultaneously
  199.             ldb pia_col
  200.             eorb #%11101110             ;will be 0 iff "RUN" + "_"
  201.             if  eq
  202.                 com keyb_enable
  203.             endif
  204.         endif
  205.         rts
  206.  
  207. ;  __  __  __  __  __  __  __  __  __  __  __  __  __  __  __  __  __  __  __
  208. ; /  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \
  209. ;|                    K E Y B O A R D   S C A N N E R                         |
  210. ; \__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/
  211.  
  212. ;       This routine is called to determine if a key is depressed
  213. ;       and if so, determine its row/column address on the keyboard,
  214. ;       then set the condition code register to reflect results.
  215.  
  216. ;       OFF/RVS, left, right and lock SHIFT keys are control keys.
  217. ;       ALL the remaining keys are non-control, but may be FUNCTION keys.
  218.  
  219. ;       Results - If no key is depressed or only the control keys are
  220. ;                 depressed then return
  221.  
  222. ;                               D = $FFFF
  223. ;                               CC= zero flag set
  224.  
  225. ;                 If the OFF/RVS key is depressed, bit 7 of reg A is set
  226.  
  227. ;                 If ANY  SHIFT  key is depressed, bit 7 of reg B is set
  228.  
  229. ;                 If BOTH OFF/RVS and SHIFT keys are depressed, OFF/RVS
  230. ;                 is assumed
  231.  
  232. ;                 If any non-control key is depressed then return
  233.  
  234. ;                       A = row    number (0 to 9) , bit 7 set accordingly
  235. ;                       B = column number (0 to 7) , bit 7 set accordingly
  236. ;                       CC= zero flag cleared
  237.  
  238. scan_keyboard   equ     *
  239.  
  240. ;       Offsets to temporary variables with respect to the stack pointer
  241.  
  242.         shift_row       equ     6               ;row number of shift keys
  243.         rvs_row         equ     8               ;row number of OFF/RVS key
  244.  
  245.         shift_mask      equ     %01000001       ;column positions of shift keys
  246.         rvs_mask        equ     %00000001       ;column position of OFF/RVS key
  247.  
  248.         shift_flag      equ     11              ;offset to shift status on stack
  249.         rvs_flag        equ     10              ;offset to OFF/RVS status on "
  250.  
  251.         row             equ     12              ;hold offset for row number
  252.         column          equ     row+1           ;hold offset for column number
  253.         results         equ     row             ;offset for row,column
  254.  
  255.         leas    -(10+2+2),s     ;open room for 10 debounced row images
  256.                                 ;            +  2 status bytes  (RVS,shift)
  257.                                 ;            +  2 result bytes  (row,column)
  258.  
  259.         lda     #9              ;___    record keyboard image...
  260.         loop                    ;   \
  261.             bsr get_col         ;    \  debounce and read all
  262.             stb a,s             ;     > columns of all 10 rows
  263.             deca                ;    /  and store them on the stack
  264.         until lt                ;___/
  265.  
  266.         ldd #shift_mask         ;___
  267.         andb shift_row,s        ;   \
  268.         if  ne                  ;    \  set shift status and
  269.             eorb shift_row,s    ;     \ mask it in keyboard image
  270.             stb  shift_row,s    ;      >
  271.             lda  #$80           ;     /
  272.         endif                   ;    /
  273.         sta shift_flag,s        ;___/   shift_flag is $80 if shifted, 0 if not
  274.  
  275.         ldd #rvs_mask           ;___
  276.         andb rvs_row,s          ;   \
  277.         if  ne                  ;    \  set OFF/RVS status and
  278.             eorb rvs_row,s      ;     \ mask it
  279.             stb  rvs_row,s      ;      \
  280.             clr  shift_flag,s   ;      /if (OFF/RVS + shift) then OFF/RVS only
  281.             lda  #$80           ;     /
  282.         endif                   ;    /
  283.         sta rvs_flag,s          ;___/   rvs_flag is $80 if depressed, 0 if not
  284.  
  285.         lda #9
  286.         loop
  287.             ldb a,s             ;A = row number, B = row's contents
  288.         quif ne                 ;quit when a key is sensed
  289.             deca
  290.         until lt                ;until all rows exhosted
  291.  
  292.         tstb
  293.         if  eq
  294.             ldd #$ffff          ;no non-control key is depressed
  295.         else
  296.             ora rvs_flag,s      ;A <-- row number + OFF/RVS status
  297.             sta row,s           ;record the row and OFF/RVS status
  298.  
  299.             lda #8              ;compute column number
  300.             loop
  301.                 deca
  302.                 aslb            ;C <-- b7.....b0 <-- 0
  303.             until cs            ;done when carry is set since B<>0
  304.  
  305.             ora shift_flag,s    ;A <-- column number + shift status
  306.             sta column,s        ;record column number+ shift status
  307.  
  308.             ldd results,s       ;results point to rvs_glag,shift_flag
  309.             bsr verify_coord    ;verify coordinates and allow for rollover
  310.  
  311.         endif
  312.  
  313.         leas (10+2+2),s         ;remove all temporary storage
  314.  
  315.         cmpd #$ffff             ;set CC register
  316.  
  317.         rts
  318.  
  319. ;  __  __  __  __  __  __  __  __  __  __  __  __  __  __  __  __  __  __  __
  320. ; /  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \
  321. ;|       D E B O U N C E   A   R O W   T H E N   R E A D    C O L U M N S    |
  322. ; \__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/
  323.  
  324. get_col equ     *       ;read columns of the row pointed to by the contents
  325.                         ;of the A accumulator
  326.                         ;return
  327.                         ;       A = unchanged
  328.                         ;       B = bit map of the columns in this row
  329.                         ;               1 bit set for each key depressed
  330.                         ;       CC= zero if no key in this row depressed
  331.                         ;         <>zero otherwise
  332.  
  333.         sta     pia_row         ;select a row pointed to by A
  334.         pshs    a
  335.  
  336.         loop                    ;___
  337.             ldb pia_col         ;   \
  338.             lda debounce        ;    \
  339.             loop                ;     \
  340.                 deca            ;      >    debounce keyboard
  341.             until eq            ;     /
  342.             cmpb pia_col        ;    /
  343.         until eq                ;___/
  344.  
  345.         comb                    ;set cc and return result
  346.  
  347.         puls a,pc               ;restore A and return from subroutine
  348.  
  349.  
  350. ;  __  __  __  __  __  __  __  __  __  __  __  __  __  __  __  __  __  __  __
  351. ; /  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \
  352. ;| M A T R I X   C O O R D I N A T E S  T O  A S C I I   C O N V E R S I O N |
  353. ; \__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/
  354.  
  355. ;                       convert_to_ascii
  356. ;  Input -  Accumulator A contains the keyboard row number
  357. ;           bit 7 is set if the OFF/RVS key was depressed
  358.  
  359. ;           Accumulator B contains the keyboard column number
  360. ;           bit 7 is set if the left, right or lock SHIFT key was depressed
  361.  
  362. ;  Result - Accumulator B contains the character representation corresponding
  363. ;           to keyboard's row/column address
  364.  
  365. convert_to_ascii equ *
  366.  
  367.         shift_offset    equ     80
  368.         control_offset  equ     shift_offset + 80
  369.  
  370.         pshs x,b        ;preserve x register
  371.                         ;save register B for now
  372.  
  373.                         ; no need to get rid of control flag in
  374.                         ; accumulator A, since it represents 4 orders
  375.                         ; of magnitute shift w.r.t the row number
  376.                         ; which is less than 10 (one nibble)
  377.         ldb  #$08
  378.         mul             ; D <-- ($80*RVS + row)*8    A = $04*RVS , B= row*8
  379.  
  380.         leax ascii_table,pc
  381.         abx             ; x = address of table + 8 * row  (abx since row*8<80)
  382.  
  383.         puls b          ; now we are ready to use the column information
  384.  
  385.         tsta            ; if A <> 0 then RVS flag was set before multiplication
  386.         if  ne
  387.             leax control_offset,x
  388.         else
  389.             tstb
  390.             if  lt
  391.                 leax shift_offset,x
  392.             endif
  393.         endif
  394.  
  395.         andb #$7f       ; get rid of the shift status
  396.         ldb b,x         ; get the ascii character
  397.         clra
  398.  
  399.         puls x,pc       ;return from subroutine
  400.  
  401. ;  __  __  __  __  __  __  __  __  __  __  __  __  __  __  __  __  __  __  __
  402. ; /  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \
  403. ;| V E R I F Y   M A C R O   F O R   K E Y B O A R D   C O O R D I N A T E S |
  404. ;|    and  2   K E Y S   R O L L   O V E R   G E N E R A T O R  (optional)   |
  405. ; \__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/
  406.  
  407.  
  408. ;               Will verify correctness of coordinates and
  409. ;               check for 2 keys rool over
  410. ;               may be omitted if it causes too much overhead
  411.  
  412. ;               Verification is done be reading the matrix coordinates
  413. ;               backwards.
  414.  
  415. ;               If the resultant coordinates are in agreement with the
  416. ;               original set then return the original set.
  417.  
  418. ;               If the interpretation depends on the way we read the matrix,
  419. ;               then
  420. ;                  if any of the coordinates equals to the last set
  421. ;                  then
  422. ;                       return the one which is not the same
  423. ;                  else
  424. ;                       return $ffff, rejecting this result.
  425.  
  426. verify_coord    equ     *       ;On entry D = new_up_coord
  427.                                 ;On exit  D = verified coordinates
  428.  
  429.         pshs    y,x,d           ;D = new_up_coord  , save X and Y
  430.  
  431.                                 ;0,S = D  = new_up_coord
  432.                                 ;2,S = X
  433.                                 ;4,S = Y
  434.                                 ;6,S = PC
  435.                                 ;8,S = keyboard image
  436.  
  437.         ldb #7                  ;point to one byte prior to first row
  438.         loop                    ;start the scan with row 0
  439.             incb
  440.             lda b,s
  441.         until ne                ;A = columns, B = row when done
  442.  
  443.         subb #8
  444.         orb rvs_flag+8,s        ;add OFF/RVS attribute to the row
  445.         pshs b
  446.  
  447.         ldb #-1                 ;generate column number
  448.         loop                    ;using right hand rotation
  449.             incb
  450.             lsra
  451.         until cs                ;B = column number when done
  452.  
  453.         puls a                  ;A <-- (OFF/RVS flag + row number)
  454.         orb  shift_flag+8,s     ;B <-- (shift flag + column number)
  455.  
  456.                                 ;D = new_down_coord
  457.  
  458.         cmpd    0,s                     ;[0,S] = new_up_coord
  459.         if      eq                      ;if (new_up = new_down)
  460.                 std     old_up_coord
  461.                 std     old_down_coord
  462.         else
  463.                 ldy     0,s             ;Y = new_up_coord
  464.                 tfr     d,x             ;X = new_down_coord
  465.                 guess                           ;\  if
  466.                         cmpx    old_down_coord  ; \     (old_down_coord =
  467.                 quif    ne                      ;  \       new_down_coord )
  468.                                                 ;   > &
  469.                         cmpy    old_up_coord    ;  /    (old_up_coord   =
  470.                 quif    ne                      ; /        new_up_coord )
  471.                         ldd     prev_coord      ;/   then  return prev_coord
  472.                 admit                           ;    else  go on
  473.                         cmpy    old_up_coord
  474.                         if      eq              ;if (new_up=old_up) then
  475.                                 tfr     x,d     ;     return new_down_coord
  476.                         else                    ;else
  477.                                 cmpx    old_down_coord
  478.                                 if      eq      ;    if (old_down=new_down) then
  479.                                         tfr y,d ;       return new_up_coord
  480.                                 else            ;    else
  481.                                         ldd #-1 ;       return $ffff
  482.                                         tfr d,x
  483.                                         tfr d,y
  484.                                 endif           ;    endif
  485.                         endif                   ;endif
  486.                 endguess                        ;    endif
  487.                 stx     old_down_coord
  488.                 sty     old_up_coord
  489.         endif
  490.  
  491.         leas    2,s
  492.         puls    x,y,pc
  493. end
  494. ;  __  __  __  __  __  __  __  __  __  __  __  __  __  __  __  __  __  __  __
  495. ; /  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \
  496. ;|          SuperPET and Commodore 8032 Keyboard matrix map                   |
  497. ; \__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/\__/
  498.  
  499.  
  500. ascii_table     equ     *       ;will be change to suit OS/9
  501.  
  502. ;       Lower Case Keyboard values
  503.  
  504. ;                               <-- columns -->
  505. ;     0   1   2   3   4   5   6   7  rows  0   1   2   3   4   5   6   7
  506.  
  507.  fcb '2 ,'5 ,'8 ,'- ,'8 ,$07,$ff,$ff  ;0|  2   5   8   -  *8  ==>
  508.  fcb '1 ,'4 ,'7 ,'0 ,'7 ,'^ ,$ff,'9   ;1|  1   4   7   0  *7   ^      *9
  509.  fcb $06,'s ,'f ,'h ,'] ,'k ,'; ,'5   ;2| ESC  s   f   h   ]   k   ;  *5
  510.  fcb 'a ,'d ,'g ,'j ,$0d,'l ,'@ ,'6   ;3|  a   d   g   j  CR   l   @  *6
  511.  fcb $09,'w ,'r ,'y ,'\ ,'i ,'p ,$04  ;4| TAB  w   r   y   \   i   p  DEL
  512.  fcb 'q ,'e ,'t ,'u ,$0a,'o ,'[ ,'4   ;5|  q   e   t   u CRDWN o   [  *4
  513.  fcb $ff,'c ,'b ,'. ,'. ,$ff,$ff,'3   ;6|SHIFT c   b   .  *.    SHIFT *3
  514.  fcb 'z ,'v ,'n ,', ,'0 ,$ff,$7f,'2   ;7|  z   v   n   ,  *0      RUB *2
  515.  fcb $ff,'x ,$20,'m ,$01,$ff,'/ ,'1   ;8|RVS   x  SP   m HOME      /  *1
  516.  fcb '_ ,'3 ,'6 ,'9 ,$03,': ,$ff,$ff  ;9|  _   3   6   9 STOP  :
  517. ;                                     * a character preceded by an asterisk
  518. ;                                               is on the keypaad
  519.  
  520. ;       Upper Case Keyboard values
  521.  
  522. ;                               <-- columns -->
  523. ;     0   1   2   3   4   5   6   7  rows  0   1   2   3   4   5   6   7
  524.  
  525.  fcb '" ,'% ,'( ,'= ,$88,$08,$ff,$ff  ;0|  "   %   (   =  f8  <==  .. ..
  526.  fcb '! ,'$ ,'' ,'0 ,$87,'~ ,$ff,$89  ;1|  !   $   '   0  f7   ~      f9
  527.  fcb $06,'S ,'F ,'H ,'} ,'K ,'+ ,$85  ;2|EEOL  S   F   H   }   K   +  f5
  528.  fcb 'A ,'D ,'G ,'J ,$0d,'L ,'` ,$86  ;3|  A   D   G   J  CR   L   `  f6
  529.  fcb $09,'W ,'R ,'Y ,'| ,'I ,'P ,$05  ;4| TAB  W   R   Y   |   I   P  INST
  530.  fcb 'Q ,'E ,'T ,'U ,$0b,'O ,'{ ,$84  ;5|  Q   E   T   U CRSUP O   {  f4
  531.  fcb $ff,'C ,'B ,'> ,$8b,$ff,$ff,$83  ;6|SHIFT C   B   >  f.  ..SHIFT f3
  532.  fcb 'Z ,'V ,'N ,'< ,$8a,$ff,$7f,$82  ;7|  Z   V   N   <  f0  ..  RUB f2
  533.  fcb $ff,'X ,$20,'M ,$0c,$ff,'? ,$81  ;8|RVS   X  SP   M CLR  ..   ?  f1
  534.  fcb '_ ,'# ,'& ,') ,$02,'* ,$ff,$ff  ;9|  _   #   &   ) RUN   *  ..  ..
  535. ;                                       a character preceded by an f
  536. ;                                               is on the keypad
  537.  
  538. ;       Control characters Keyboard values
  539.  
  540. ;                               <-- columns -->
  541. ;     0   1   2   3   4   5   6   7  rows  0   1   2   3   4   5   6   7
  542.  
  543.  fcb '2 ,'5 ,'8 ,'- ,$93,$07,$ff,$ff  ;0|  2   5   8   -  F8  ==>  .. ..
  544.  fcb '1 ,'4 ,'7 ,$80,$92,$1e,$ff,$94  ;1|  1   4   7  BRK F7   ^^  .. F9
  545.  fcb $06,$81,$06,$08,$1d,$0b,'; ,$90  ;2|EEOL ^s  ^f  ^h  ^]  ^k   ;  F5
  546.  fcb $01,$85,$7f,$0a,$0d,$0c,$00,$91  ;3| ^a  ^d  ^g  ^j  CR  ^l  ^@  F6
  547.  fcb $09,$17,$12,$19,$1c,$09,$10,$04  ;4| TAB ^w  ^r  ^y  ^\  ^i  ^p  DEL
  548.  fcb $83,$05,$89,$87,$0a,$86,$1b,$8f  ;5| ^q  ^e  ^t  ^u CRDWN^o  ^[  F4
  549.  fcb $ff,$8b,$07,'. ,$96,$ff,$ff,$8e  ;6|SHIFT^c  ^b   .  F.  ..SHIFT F3
  550.  fcb $82,$88,$84,', ,$95,$ff,$7f,$8d  ;7| ^z  ^v  ^n   ,  F0  ..  RUB F2
  551.  fcb $ff,$18,$20,$0d,$01,$ff,'/ ,$8c  ;8|RVS  ^x  SP  ^m HOME ..   /  F1
  552.  fcb $1f,'3 ,'6 ,'9 ,$ff,': ,$ff,$ff  ;9| ^_   3   6   9 STOP  :  ..  ..
  553.  
  554. ;                                       a character preceded by an F
  555. ;                                               is on the keypad
  556.  
  557. end
  558.